package haw.its.a2;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class HC2 {

	/**
	 * Applies TripleDES with CFB Mode
	 * 
	 * @param InputFile
	 * @param KeyFile
	 * @param Outputfile
	 * @param Status
	 *            ("encrypt" or "decrypt")
	 * @see http://de.wikipedia.org/wiki/Cipher_Feedback_Mode
	 */
	public static void main(String[] args) {
		String file = args[0];
		String keyFile = args[1];
		String fileOut = args[2];
		String status = args[3];

		FileInputStream keyStream = null;
		byte[] key1 = new byte[8];
		byte[] key2 = new byte[8];
		byte[] key3 = new byte[8];
		byte[] iv = new byte[8];

		try {
			keyStream = new FileInputStream(keyFile);

			keyStream.read(key1, 0, 8);
			keyStream.read(key2, 0, 8);
			keyStream.read(key3, 0, 8);
			keyStream.read(iv, 0, 8);

		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				keyStream.close();
			} catch (IOException e) {
				e.printStackTrace();
			}

		}

		DES DES1 = new DES(key1);
		DES DES2 = new DES(key2);
		DES DES3 = new DES(key3);

		FileInputStream in = null;
		FileOutputStream out = null;

		byte[] inputText = new byte[8];
		byte[] fkc = new byte[8];
		byte[] outputText = new byte[8];

		try {
			in = new FileInputStream(file);
			out = new FileOutputStream(fileOut);

			fkc = tripleDES(DES1, DES2, DES3, iv);

			int len = 0;
			while ((len = in.read(inputText)) > 0) {
				for (int i = 0; i < inputText.length; i++) {
					outputText[i] = (byte) (fkc[i] ^ inputText[i]);
				}

				out.write(outputText, 0, len);

				if (status.equals("encrypt")) {
					fkc = tripleDES(DES1, DES2, DES3, outputText);
				} else {
					fkc = tripleDES(DES1, DES2, DES3, inputText);
				}
			}

		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				in.close();
				out.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

	}

	/**
	 * Only Encryption Function necessary
	 * 
	 * @see http://de.wikipedia.org/wiki/Cipher_Feedback_Mode
	 * @param des1
	 * @param des2
	 * @param des3
	 * @param inputUser
	 * @return
	 */
	private static byte[] tripleDES(DES des1, DES des2, DES des3,
			byte[] inputUser) {
		byte[] input = inputUser.clone();
		byte[] output = new byte[8];
		des1.encrypt(input, 0, output, 0);
		des2.decrypt(output, 0, input, 0);
		des3.encrypt(input, 0, output, 0);
		return output;
	}

	/*
	 * RunConfigs
	 * 
	 * "src\haw\its\a2\Klar.txt" "src\haw\its\a2\3DESTest.key"
	 * "src\haw\its\a2\3DESKlartxtEnc.txt" encrypt
	 * 
	 * "src\haw\its\a2\3DESKlartxtEnc.txt" "src\haw\its\a2\3DESTest.key"
	 * "src\haw\its\a2\KlarDES.txt" decrypt
	 * 
	 * "src\haw\its\a2\3DESTest.enc" "src\haw\its\a2\3DESTest.key"
	 * "src\haw\its\a2\3DESTest.pdf" decrypt
	 */
}